package com.atguigu.spzx.product.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.atguigu.spzx.common.constant.RedisConst;
import com.atguigu.spzx.model.dto.h5.ProductSkuDto;
import com.atguigu.spzx.model.entity.product.Product;
import com.atguigu.spzx.model.entity.product.ProductSku;
import com.atguigu.spzx.model.vo.h5.ProductItemVo;
import com.atguigu.spzx.product.mapper.ProductDetailsMapper;
import com.atguigu.spzx.product.mapper.ProductMapper;
import com.atguigu.spzx.product.mapper.ProductSkuMapper;
import com.atguigu.spzx.product.service.ProductService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private ProductDetailsMapper productDetailsMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public List<ProductSku> findProductSkuBySale() {
        return productMapper.selectProductSkuBySale();
    }

    @Override
    public PageInfo<ProductSku> findByPage(Integer page, Integer limit, ProductSkuDto productSkuDto) {
        PageHelper.startPage(page,limit);
        //PageInfo<ProductSku> pageInfo=productSkuMapper.findByPage(productSkuDto);
        List<ProductSku> productSkuList = productSkuMapper.findByPage(productSkuDto);
        return new PageInfo<>(productSkuList);
        //return pageInfo;
    }

    @Override
    //@Cacheable(value = RedisConst.SKUKEY_PREFIX + "#skuId" + RedisConst.SKUKEY_SUFFIX)
    public ProductItemVo item(Long skuId) {
        ProductItemVo vo = null;


        String redisKey=RedisConst.SKUKEY_PREFIX + skuId + RedisConst.SKUKEY_SUFFIX;
        String productItemVoJsonStr = redisTemplate.opsForValue().get(redisKey);
        if(StringUtils.hasText(productItemVoJsonStr)){
            vo= JSON.parseObject(productItemVoJsonStr, ProductItemVo.class);
            System.out.println("从redis获取");
            return vo;
        }

        vo=getItemFromDb(skuId);//从数据库查询封装
        if (vo==null){
            vo = new ProductItemVo();
            redisTemplate.opsForValue().set(RedisConst.SKUKEY_PREFIX + skuId + RedisConst.SKUKEY_SUFFIX,
                    JSON.toJSONString(vo),RedisConst.SKUKEY_EMPTY_TIMEOUT, TimeUnit.SECONDS);
            System.out.println("从MySQL数据库中没有查询到数据..., 向Redis中存储了空对象....ProductItemVo=" + vo);
        }else {
            redisTemplate.opsForValue().set(redisKey,JSON.toJSONString(vo),RedisConst.SKUKEY_TIMEOUT, TimeUnit.SECONDS);
            System.out.println("从数据库获取");
        }

        return vo;
    }

    private ProductItemVo getItemFromDb(Long skuId) {

        try {
            ProductItemVo vo = new ProductItemVo();
            //查询所有结果放进vo
            ProductSku productSku=productSkuMapper.selectById(skuId);
            vo.setProductSku(productSku);

            Product product=productMapper.selectById(productSku.getProductId());
            vo.setProduct(product);

            List<String> sliderUrlList=Arrays.asList(product.getSliderUrls().split(","));
            vo.setSliderUrlList(sliderUrlList);

            List<String> detailsImageUrlList=Arrays.asList(productDetailsMapper.selectByProductId(product.getId()).getImageUrls().split(","));
            vo.setDetailsImageUrlList(detailsImageUrlList);

            JSONArray specValueList=JSONArray.parseArray(product.getSpecValue());
            vo.setSpecValueList(specValueList);

            List<ProductSku> productSkuList=productSkuMapper.selectByProductId(product.getId());
            Map<String,Object> map=new HashMap<>();
            for (ProductSku sku : productSkuList) {
                map.put(sku.getSkuSpec(),sku.getId());
            }
            vo.setSkuSpecValueMap(map);
            return vo;
        } catch (Exception e){
            return null;
        }

    }

    @Override
    public ProductSku getBySkuId(Long skuId) {
        return productSkuMapper.selectBySkuId(skuId);
    }
}
